﻿using DAL;
using Models;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;


namespace SMProject
{
    public partial class FrmSaleManage : Form
    {
        private SalesPersonService personService = new SalesPersonService();

        private ProductService productService = new ProductService();
        private List<Product> productList = new List<Product>();  //定义一个list集合，保存商品对象
        private BindingSource bs = new BindingSource();  //定义一个数据绑定对象（在DataGridView和List之间使用）


        #region  窗体拖动、关闭【实际项目中不用】

        private Point mouseOff;//鼠标移动位置变量
        private bool leftFlag;//标签是否为左键
        private void FrmMain_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                mouseOff = new Point(-e.X, -e.Y); //得到变量的值
                leftFlag = true;                  //点击左键按下时标注为true;
            }
        }
        private void FrmMain_MouseMove(object sender, MouseEventArgs e)
        {
            if (leftFlag)
            {
                Point mouseSet = Control.MousePosition;
                mouseSet.Offset(mouseOff.X, mouseOff.Y);  //设置移动后的位置
                Location = mouseSet;
            }
        }
        private void FrmMain_MouseUp(object sender, MouseEventArgs e)
        {
            if (leftFlag)
            {
                leftFlag = false;//释放鼠标后标注为false;
            }
        }

        #endregion


        public FrmSaleManage()
        {
            InitializeComponent();
            this.lblSerialNum.Text = CreateSerialNum();  //生成流水号
            this.lblSalePerson.Text = Program.currentPerson.SPName;  //展示当前用户名

            this.dgvProdutList.AutoGenerateColumns = false;
        }

        //生成流水号
        public string CreateSerialNum()
        {
            string serialNum = personService.getDBServerTime().ToString("yyyyMMddHHmmssms");
            Random random = new Random();
            serialNum += random.Next(10, 99).ToString();


            return serialNum;
        }


        //窗体关闭前，写入退出日志
        private void FrmSaleManage_FormClosing(object sender, FormClosingEventArgs e)
        {
            DialogResult result = MessageBox.Show("确认退出吗", "退出询问",
                                    MessageBoxButtons.OKCancel, MessageBoxIcon.Question);
            if (result == DialogResult.Cancel)
            {
                e.Cancel = true;
            }
            else
            {
                DateTime dateTime = personService.getDBServerTime();
                personService.WriteExitLog(Program.currentPerson.LoginLogId, dateTime);
            }

        }



        //扫描商品条码（输入+回车）、上下移动选择商品、删除商品、商品计算、系统退出事件的“入口”

        private void txtProductId_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.F10)  //f10对应功能
            {
                DialogResult result = MessageBox.Show("确认退出吗", "退出询问", MessageBoxButtons.OKCancel, MessageBoxIcon.Question);
                if (result == DialogResult.Cancel)
                {
                    return;
                }
                else
                {
                    this.Close();
                }
            }
            else if (e.KeyValue == 13)  //如果是回车键，则将当前商品添加到上面的列表中
            {
                //【1】验证输入信息是否合法
                if (!ValidateInput()) return;
                //根据商品编号从当前商品列表集合中查询商品对象（使用linq）
                var pList = from p in this.productList
                            where p.ProductId.Equals(this.txtProductId.Text.Trim())
                            select p;
                if (pList.Count() == 0)  //【2】如果当前列表中不存在该商品，则向当前商品列表中添加一个新的商品对象
                {
                    AddNewProductToList();
                }
                else    //【3】如果商品对象已经存在，则更新商品的数量和小计金额
                {
                    Product pdt = pList.FirstOrDefault<Product>();
                    pdt.Quantity += Convert.ToInt32(this.txtQuantity.Text.Trim());
                    pdt.SubTotal = pdt.Quantity * pdt.UnitPrice;
                    if (pdt.Discount != 0)
                    {
                        pdt.SubTotal = pdt.SubTotal * pdt.Discount / 10;
                    }

                }

                //【4】显示商品列表
                this.bs.DataSource = this.productList;  //设置bindingsource的数据源
                this.dgvProdutList.DataSource = null;
                this.dgvProdutList.DataSource = this.bs;  //bindingsource作为数据源

                //【5】更新商品总金额【使用linq，也可对list进行遍历】
                this.lblTotalMoney.Text = (from p in this.productList select p.SubTotal).Sum().ToString();

                //【6】清空商品的相关信息（不会影响下一次的数据）
                this.txtProductId.Clear();
                this.txtQuantity.Text = "1";
                this.txtDiscount.Text = "0";
                this.txtUnitPrice.Text = "0.00";
                this.lblReceivedMoney.Text = "0.0";
                this.lblReturnMoney.Text = "0.0";
                this.txtProductId.Focus();
            }

            else if (e.KeyValue == 38)  //向上移动
            {
                if (this.dgvProdutList.RowCount == 0 || this.dgvProdutList.RowCount == 1) return;
                this.bs.MovePrevious();
            }
            else if (e.KeyValue == 40)  //向下移动
            {
                if (this.dgvProdutList.RowCount == 0 || this.dgvProdutList.RowCount == 1) return;
                this.bs.MoveNext();
            }
            else if (e.KeyValue == 46)  //删除当前行
            {
                if (this.dgvProdutList.RowCount == 0) return;
                this.bs.RemoveCurrent();  //  通过bindingsource对象删除当前行（不仅是从显示中删除，同时绑定的集合中对应也删除）
                this.dgvProdutList.DataSource = null;
                this.dgvProdutList.DataSource = this.bs;

            }
            else if (e.KeyCode == Keys.F2)  //如果用户按的是f2键，则进入商品结算
            {
                if (this.dgvProdutList.RowCount == 0) return;
                else
                    Balance();
            }
        }

        private void Balance()
        {
            //显示商品结算窗口，考虑结算被取消或者修改的情况
            FrmBalance frmBalance = new FrmBalance(this.lblTotalMoney.Text.Trim());
            if (frmBalance.ShowDialog() != DialogResult.OK)  //如果结算被取消或修改
            {
                if (frmBalance.Tag.ToString() == "F4")  //用户放弃本次购买（如：忘记带钱）
                {
                    ResetForm();  //重新生成流水号,等待结算下一个客户的商品
                }
                else if (frmBalance.Tag.ToString() == "F5")  //用户放弃部分商品购买（如：带钱不够）
                {
                    this.txtProductId.Focus();
                }
            }
            else
            {
                //进入正式的结算:获取用户的实付金额和会员卡号（如果有）
                SMMember member = null;
                if (frmBalance.Tag.ToString().Contains('|'))  //如果有会员卡，则将会员卡号和实付金额分开
                {
                    string[] info = frmBalance.Tag.ToString().Split('|');
                    this.lblReceivedMoney.Text = info[0];
                    member = new SMMember()
                    {
                        MemberId = Convert.ToInt32(info[1]),
                        Points = (int)(Convert.ToDouble(info[0]) / 10.0)  //计算本次消费所得积分
                    };
                }
                else
                {
                    this.lblReceivedMoney.Text = frmBalance.Tag.ToString();
                }
                //显示找零
                this.lblReceivedMoney.Text = (Convert.ToDecimal(this.lblReceivedMoney.Text.Trim()) - Convert.ToDecimal(this.lblTotalMoney.Text)).ToString();

                //创建商品对象
                SalesListMain salesList = new SalesListMain()
                {
                    SerialNum = this.lblSerialNum.Text.Trim(),
                    TotalMoney = Convert.ToDecimal(this.lblTotalMoney.Text.Trim()),
                    RealReceive = Convert.ToDecimal(this.lblReceivedMoney.Text.Trim()),
                    ReturnMoney = Convert.ToDecimal(this.lblReturnMoney.Text.Trim()),
                    SalesPersonId = Program.currentPerson.SalePersonId
                };

                //封装商品列表明细
                foreach (Product item in this.productList)
                {
                    salesList.salesLists.Add(new SalesListDetail()
                    {
                        SerialNum = this.lblSerialNum.Text.Trim(),
                        ProductId = item.ProductId,
                        ProductName = item.ProductName,
                        Quantity = item.Quantity,
                        UnitPrice = item.UnitPrice,
                        Discount = item.Discount,
                        SubTotalMoney = item.SubTotal
                    });
                }

                try
                {
                    productService.SaveSaleInfo(salesList, member);
                }
                catch (Exception ex)
                {
                    MessageBox.Show("保存销售数据的时候发生错误：" + ex.Message, "错误提示");
                    return;
                }
                //打印小票

                //重新生成流水号，等待结算下一个客户的商品
                ResetForm();
            }
        }

        private void ResetForm()
        {
            this.lblSerialNum.Text = this.CreateSerialNum();
            this.dgvProdutList.DataSource = null;
            this.productList.Clear();  //从商品列表集合中清除所有的商品对象
            this.lblTotalMoney.Text = "0.00";
            this.txtProductId.Focus();
        }

        private void AddNewProductToList()
        {
            //（1）根据商品编号查询商品信息
            Product product = productService.GetProductById(this.txtProductId.Text.Trim());
            if (product == null)    //如果数据库中没有该商品编码，则认为是临时商品，或输错的商品
            {
                //可以在这里提示销售员...(当前商品不存在！确认是临时商品吗？)
                product = new Product()
                {
                    ProductId = this.txtProductId.Text.Trim(),
                    ProductName = "暂时没有提供商品名称",
                    UnitPrice = Convert.ToDecimal(this.txtUnitPrice.Text.Trim()),
                    Discount = Convert.ToInt32(this.txtDiscount.Text.Trim())  //目前只允许输入整数
                };

            }
            else    //如果数据库中存在该商品，则显示单价和折扣
            {
                this.txtUnitPrice.Text = product.UnitPrice.ToString();
                this.txtDiscount.Text = product.Discount.ToString();
            }

            //(2)  根据商品数量和单价计算小计金额
            product.Quantity = Convert.ToInt32(this.txtQuantity.Text.Trim());
            product.SubTotal = product.Quantity * product.UnitPrice;


            //（3）如果有折扣，则计算折扣后的商品金额
            if (product.Discount != 0)
            {
                product.SubTotal = product.SubTotal * product.Discount / 10;
            }
            //CalcDiscount( product);

            //（4）添加商品序号
            product.Num = this.productList.Count() + 1;

            //（5）将商品对象添加到商品列表中
            this.productList.Add(product);

            this.bs.MoveLast();  //最后一行选中
        }


        //销售员输入信息的验证
        private bool ValidateInput()
        {
            if (this.txtProductId.Text.Trim().Length == 0) return false;
            //验证商品编码必须是数字（使用正则表达式）
            //验证商品单价、折扣是否符合要求

            return true;
        }

        /// <summary>
        /// 数量、单价、折扣等文本框接收到回车键时，自动聚焦到商品编号
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void txtOthers_KeyUp(object sender, KeyEventArgs e)
        {
            if (e.KeyValue == 13)
            {
                this.txtProductId.Focus();
            }
        }


        /// <summary>
        /// 从列表中删除商品后，更新总金额和序号
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void dgvProdutList_RowsRemoved(object sender, DataGridViewRowsRemovedEventArgs e)
        {
            //更新商品的总金额
            this.lblTotalMoney.Text = (from p in this.productList select p.SubTotal).Sum().ToString();

            //更新序号
            for (int i = 0; i < this.productList.Count; i++)
                this.productList[i].Num = i + 1;
        }

        private void FrmSaleManage_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.F10)  //f10对应功能
            {
                DialogResult result = MessageBox.Show("确认退出吗", "退出询问", MessageBoxButtons.OKCancel, MessageBoxIcon.Question);
                if (result == DialogResult.Cancel)
                {
                    return;
                }
                else
                {
                    this.Close();
                }
            }
        }
    }
}
